/**
 * Java Enterprise in a Nutshell, Third Edition, 
 * by Jim Farley and William Crawford 
 * with Prakash Malani, John G. Norman, and Justin Gehtland. 
 * Copyright 2006 O'Reilly Media, Inc., 0-596-10142-2.
 *
 * Modified by Vladimir Tarasov, 2009-08-26.
 * Tested with JDK 1.6.
 * 
 * Before running the client, start AccountServer first,
 * then press Shift+F6 to run AccountClient.
 * 
 * If you want to run the example locally, change the host name below.
 */
package tavl_rmi.simple;

import tavl_rmi.account.InsufficientFundsException;
import tavl_rmi.account.Account;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

/**
 * AccountClient: A simple example client for an RMI-exported Account.
 */
public class AccountClient {

    /**
     * references to the proxies for the remote objects
     */
    private Account jimAcct, billAcct;

    public static void main(String argv[]) {
        AccountClient client = new AccountClient();
        client.makeDeposit();
        client.transferMoney();
    }

    /**
     * Find remote objects and get references to their proxies
     */
    public AccountClient() {
        // rmiregistry on the lab server listens to port 1099
        final String host = "rmi://127.0.0.1:1099/";
        try {
            // Lookup remote account objects
            jimAcct = (Account) Naming.lookup(host + "JimF");
            billAcct = (Account) Naming.lookup(host + "Bill");
        } catch (RemoteException re) {
            System.err.println("Remote exception while looking up account: " + re.getMessage());
        } catch (NotBoundException nbe) {
            System.err.println("Server object not found at expected URL: " + nbe.getMessage());
        } catch (MalformedURLException mue) {
            System.err.println("Bad RMI URL given for server object: " + mue.getMessage());
        }
    }

    /**
     * Make deposits to the remote objects
     */
    private void makeDeposit() {
        try {
            // Make deposit to the 1st remote object
            jimAcct.deposit(12000);
            // Report results and balance.
            System.out.println("Deposited 12,000 into account owned by " + jimAcct.getName());
            System.out.println("Balance now totals: " + jimAcct.getBalance() + "\n");
            // Make deposit to the 2nd remote object
            billAcct.deposit(15000);
            System.out.println("Deposited 15,000 into account owned by " + billAcct.getName());
            System.out.println("Balance now totals: " + billAcct.getBalance() + "\n");
        } catch (RemoteException re) {
            System.err.println("Remote exception while makinging deposit : "
                    + re.getMessage());
        }
    }

    /**
     * Transfer money from the 2nd remote account to the 1st one
     */
    private void transferMoney() {
        try {
            // billAcct is passed by reference and used as a remote object by
            // the server.
            jimAcct.transfer(5000, billAcct);
            System.out.println("\nTransferred 5,000 from account " + billAcct.getName() + " into account " + jimAcct.getName());
            System.out.println("JimF's balance now totals: " + jimAcct.getBalance());
            System.out.println("Bill's balance now totals: " + billAcct.getBalance());
        } catch (RemoteException re) {
            System.err.println("Remote exception while transferring money: "
                    + re.getMessage());
        } catch (InsufficientFundsException ife) {
            System.err.println("InsufficientFundsException : " + ife.getMessage());
        }
    }
}
